package com.gaogzhen.juc.atomic.cln;

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * @author Administrator
 */
public class ChmTest01 {
    public static void main(String[] args) {
//        test01();
        demo01(
                (Supplier<Map<String, LongAdder>>) ConcurrentHashMap::new,
                (map, words) -> {
                    for (String word: words) {
                        LongAdder adder = map.computeIfAbsent(word, (key) -> new LongAdder());
                        adder.increment();
                    }
                }
        );
    }

    public static <V> void demo01(Supplier<Map<String, V>> supplier, BiConsumer<Map<String, V>, List<String>> consumer) {
        Map<String, V> conterMap = supplier.get();
        List<Thread> ts = new ArrayList<>();
        for (int i = 1; i <= 26; i++) {
            int idx = i;
            Thread thread = new Thread(() -> {
                List<String> words = readFromFile(idx);
                consumer.accept(conterMap, words);
            });
            ts.add(thread);
        }
        ts.forEach(Thread::start);
        ts.forEach(t -> {
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        System.out.println(conterMap);
    }

    private static List<String> readFromFile(int idx) {
        ArrayList<String> words = new ArrayList<>();
        try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream("words/" + idx + ".txt")))) {
            while (true) {
                String word = in.readLine();
                if (word == null) {
                    break;
                }
                words.add(word);
            }
            return words;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void test01() {
        final String ALPHA = "abcdefghijklmnopqrstuvwxyz";

        int length = ALPHA.length();
        int count  = 200;
        List<String> list = new ArrayList<>(length * count);
        for (int i = 0; i < length; i++) {
            char ch = ALPHA.charAt(i);
            for (int j = 0; j < count; j++) {
                list.add(String.valueOf(ch));
            }
        }

        Collections.shuffle(list);
        for (int i = 0; i < 26; i++) {
            try(PrintWriter pw = new PrintWriter(
                    new OutputStreamWriter(
                            new FileOutputStream("words/" + (i + 1) + ".txt")
                    )
            )) {
                String collect = list.subList(i * count, (i + 1) * count).stream()
                        .collect(Collectors.joining("\n"));
                pw.print(collect);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
}
